package com.miracle9.game.server.message;

import com.miracle9.game.util.Encrypt;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.HashMap;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service("messageSend")
public class MessageSend extends Thread {

    private static Logger logger = Logger.getLogger(MessageSend.class);
    public static StorageMethodOperating q = new StorageMethodOperating();
    private ThreadPoolExecutor r = new ThreadPoolExecutor(1, 20, 3L, TimeUnit.SECONDS, new SynchronousQueue(), new ThreadPoolExecutor.CallerRunsPolicy());
    static final String KEY_ALGORITHM = "AES";
    static final String algorithmStr = "AES/CBC/PKCS7Padding";
    private static Key key;
    private static Cipher cipher;
    public static String aIv = "dHjWxY506jk0K7W8";
    static byte[] iv;

    public MessageSend() {
        start();
    }

    public void run() {
        for (StorageMethodEntity data = q.waitOperating(); data != null; data = q.waitOperating()) {
            this.r.execute(new MessageSendThread(data));
        }
    }

    public static void sendData(StorageMethodEntity data) {
        String method = data.method;
        Object[] result = data.result;
        IoSession session = data.session;
        try {
            if(session!=null && session.containsAttribute("checkH5")){
                JSONObject res = new JSONObject();
                res.put("method",method);
                res.put("data",result) ;
            //    session.write(Encrypt.AESUNURLEncrypt(res.toString(),MinaServerHandler.key));
                MinaBean res1 = new MinaBean();
                res1.setContent(Encrypt.AESUNURLEncrypt(res.toString(),MinaServerHandler.key));
                session.write(res1);
                return;
            }
            if ("userLogin".equalsIgnoreCase(method)) {
                method = "login";
            } else if ("noticeList".equalsIgnoreCase(method)) {
                method = "getNotice";
            } else if ("exCharge".equalsIgnoreCase(method)) {
                method = "excharge";
            } else if ("getGameGold".equalsIgnoreCase(method)) {
                method = "gameGold";
            }
            HashMap map = new HashMap();
            if ("getNotice".equalsIgnoreCase(method)) {
                HashMap args = new HashMap();
                args.put("notice", java.util.Arrays.asList(result[0]));
                map.put("method", method);
                map.put("args", new Object[]{args});
            } else if ("getEmailList".equalsIgnoreCase(method)) {
                HashMap map1 = new HashMap();
                map1.put("mailList", result[0]);
                map1.put("success", Boolean.valueOf(true));
                map.put("method", method);
                map.put("args", new Object[]{map1});
            } else if ("login".equalsIgnoreCase(method)) {
                HashMap map1 = new HashMap();
                map1 = (HashMap) result[0];
                boolean isLogin = ((Boolean) map1.get("isLogin")).booleanValue();
                int msgstatus = ((Integer) map1.get("messageStatus")).intValue();
                if (!isLogin) {
                    if (msgstatus == 0) {
                        map1.put("msgCode", Integer.valueOf(3));
                        map1.put("msg", "账号或密码错误");
                        result[0] = map1;
                    } else if (msgstatus == 1) {
                        map1.put("msgCode", Integer.valueOf(6));
                        map1.put("msg", "账号被冻结,请联系管理员");
                        result[0] = map1;
                    } else if (msgstatus == 15) {
                        map1.put("msgCode", Integer.valueOf(16));
                        map1.put("msg", "网络不稳定");
                        result[0] = map1;
                    } else {
                        map1.put("msgCode", Integer.valueOf(7));
                        map1.put("msg", "登录失败!");
                        result[0] = map1;
                    }
                }
                map.put("method", method);
                map.put("args", result);
            } else if ("userAward".equalsIgnoreCase(method)) {
                HashMap map1 = new HashMap();
                map1.put("gameGold", result[0]);
                map.put("method", method);
                map.put("args", new Object[]{map1});
            } else {
                map.put("method", method);
                map.put("args", result);
            }
            JSONObject json = JSONObject.fromObject(map);
            String str = json.toString();

            //logger.info(str);

            if ("checkVersion".equalsIgnoreCase(method)) {
                str = str.replaceAll("\"false\"", "false");
            }
            if ("getActivityInfo".equalsIgnoreCase(method)) {
                str = "{\"args\":[{\"activityInfo\":{\"startDate\":\"0000-00-00 00:00:00\",\"endDate\":\"0000-00-00 00:00:00\",\"activityStatus\":0,\"id\":1}}],\"method\":\"getActivityInfo\"}";
            }
            byte[] content = str.getBytes("UTF-8");

            content = jiami(content, session);
            if(content != null){
                IoBuffer bb = IoBuffer.allocate(content.length + 4);
                bb.putInt(content.length);
                bb.put(content);
                bb.flip();
                if (session != null) {
                    session.write(bb);
                }
            }

        } catch (Exception e) {
            logger.error(method, e);
        }
    }

    public static void init(byte[] keyBytes) {
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        Security.addProvider(new BouncyCastleProvider());

        key = new SecretKeySpec(keyBytes, "AES");
        try {
            cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
    }

    public static byte[] encrypt(byte[] content, byte[] keyBytes) {
        byte[] encryptedText = (byte[]) null;
        init(keyBytes);
        try {
            iv = aIv.getBytes("utf-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        try {
            cipher.init(1, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }

    private class MessageSendThread extends Thread {

        private StorageMethodEntity t;
        public MessageSendThread(StorageMethodEntity data) {
            this.t = data;
        }

        public void run() {
            MessageSend.sendData(this.t);
        }

    }

    public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            iv = aIv.getBytes("utf-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        try {
            cipher.init(2, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }

    public static byte[] jiami(byte[] bytes, IoSession session) throws Exception {
        try {
            if (com.miracle9.game.util.GameParameterAssist.bd.containsKey(session)) {
                String key = com.miracle9.game.util.GameParameterAssist.bd.get(session);
                byte[] raw = key.getBytes("utf-8");

                return encrypt(bytes, raw);
            }
            return bytes;
        } catch (Exception ex) {
            logger.error("", ex);
        }
        return null;
    }

    public static void MessageSendThread(StorageMethodEntity storageMethodEntity) {
        // TODO Auto-generated method stub

    }

}
